home *** CD-ROM | disk | FTP | other *** search
/ STraTOS 1997 April & May / STraTOS 1 - 1997 April & May.iso / CD01 / INTERNET / SITES / LITTLE / P3SRC.ZIP / ATARI / PATTERN.C < prev    next >
Encoding:
C/C++ Source or Header  |  1996-02-07  |  43.4 KB  |  2,216 lines

  1. /**************************************************************************
  2. *                pattern.c
  3. *
  4. *  This module implements texturing functions that return a value to be
  5. *  used in a pigment or normal.
  6. *
  7. *  from Persistence of Vision(tm) Ray Tracer
  8. *  Copyright 1996 Persistence of Vision Team
  9. *---------------------------------------------------------------------------
  10. *  NOTICE: This source code file is provided so that users may experiment
  11. *  with enhancements to POV-Ray and to port the software to platforms other
  12. *  than those supported by the POV-Ray Team.  There are strict rules under
  13. *  which you are permitted to use this file.  The rules are in the file
  14. *  named POVLEGAL.DOC which should be distributed with this file. If
  15. *  POVLEGAL.DOC is not available or for more info please contact the POV-Ray
  16. *  Team Coordinator by leaving a message in CompuServe's Graphics Developer's
  17. *  Forum.  The latest version of POV-Ray may be found there as well.
  18. *
  19. * This program is based on the popular DKB raytracer version 2.12.
  20. * DKBTrace was originally written by David K. Buck.
  21. * DKBTrace Ver 2.0-2.12 were written by David K. Buck & Aaron A. Collins.
  22. *
  23. *****************************************************************************/
  24.  
  25. /*
  26.  * Some texture ideas garnered from SIGGRAPH '85 Volume 19 Number 3,
  27.  * "An Image Synthesizer" By Ken Perlin.
  28.  * Further Ideas Garnered from "The RenderMan Companion" (Addison Wesley).
  29.  */
  30.  
  31. #include "frame.h"
  32. #include "vector.h"
  33. #include "povproto.h"
  34. #include "matrices.h"
  35. #include "pattern.h"
  36. #include "texture.h"
  37. #include "image.h"
  38. #include "txttest.h"
  39. #include "colour.h"
  40.  
  41.  
  42.  
  43. /*****************************************************************************
  44. * Local preprocessor defines
  45. ******************************************************************************/
  46.  
  47.  
  48. /*****************************************************************************
  49. * Static functions
  50. ******************************************************************************/
  51.  
  52. static DBL agate PARAMS((VECTOR EPoint, TPATTERN *TPat));
  53. static DBL brick PARAMS((VECTOR EPoint, TPATTERN *TPat));
  54. static DBL checker PARAMS((VECTOR EPoint));
  55. static DBL crackle PARAMS((VECTOR EPoint));
  56. static DBL gradient PARAMS((VECTOR EPoint, TPATTERN *TPat));
  57. static DBL granite PARAMS((VECTOR EPoint));
  58. static DBL leopard PARAMS((VECTOR EPoint));
  59. static DBL mandel PARAMS((VECTOR EPoint, TPATTERN *TPat));
  60. static DBL marble PARAMS((VECTOR EPoint, TPATTERN *TPat));
  61. static DBL onion PARAMS((VECTOR EPoint));
  62. static DBL radial PARAMS((VECTOR EPoint));
  63. static DBL spiral1 PARAMS((VECTOR EPoint, TPATTERN *TPat));
  64. static DBL spiral2 PARAMS((VECTOR EPoint, TPATTERN *TPat));
  65. static DBL wood PARAMS((VECTOR EPoint, TPATTERN *TPat));
  66. static DBL hexagon PARAMS((VECTOR EPoint));
  67. static long PickInCube PARAMS((VECTOR tv, VECTOR p1));
  68.  
  69. static DBL ripples_pigm PARAMS((VECTOR EPoint, TPATTERN *TPat));
  70. static DBL waves_pigm  PARAMS((VECTOR EPoint, TPATTERN *TPat));
  71. static DBL dents_pigm  PARAMS((VECTOR EPoint));
  72. static DBL wrinkles_pigm PARAMS((VECTOR EPoint));
  73. static DBL quilted_pigm PARAMS((VECTOR EPoint, TPATTERN *TPat));
  74. static TURB *Search_For_Turb PARAMS((WARP *Warps));
  75. /* static TURB *Copy_Turb PARAMS((TURB *Old));   Unused function [AED] */
  76.  
  77.  
  78.  
  79. /*****************************************************************************
  80. *
  81. * FUNCTION
  82. *
  83. *   agate
  84. *
  85. * INPUT
  86. *
  87. *   EPoint -- The point in 3d space at which the pattern is evaluated.
  88. *   TPat   -- Texture pattern struct
  89. *
  90. * OUTPUT
  91. *
  92. * RETURNS
  93. *
  94. *   DBL value in the range 0.0 to 1.0
  95. *
  96. * AUTHOR
  97. *
  98. *   POV-Ray Team
  99. *
  100. * DESCRIPTION
  101. *
  102. * CHANGES
  103. *   Oct 1994    : adapted from agate pigment by [CY]
  104. *
  105. ******************************************************************************/
  106.  
  107. static DBL agate (EPoint, TPat)
  108. VECTOR EPoint;
  109. TPATTERN *TPat;
  110. {
  111.   register DBL noise, turb_val;
  112.   TURB* Turb;
  113.  
  114.   Turb=Search_For_Turb(TPat->Warps);
  115.  
  116.   turb_val = TPat->Vals.Agate_Turb_Scale * Turbulence(EPoint,Turb);
  117.  
  118.   noise = 0.5 * (cycloidal(1.3 * turb_val + 1.1 * EPoint[Z]) + 1.0);
  119.  
  120.   if (noise < 0.0)
  121.   {
  122.     noise = 0.0;
  123.   }
  124.   else
  125.   {
  126.     noise = min(1.0, noise);
  127.     noise = pow(noise, 0.77);
  128.   }
  129.  
  130.   return(noise);
  131. }
  132.  
  133.  
  134. /*****************************************************************************
  135. *
  136. * FUNCTION
  137. *
  138. *   brick
  139. *
  140. * INPUT
  141. *
  142. *   EPoint -- The point in 3d space at which the pattern
  143. *   is evaluated.
  144. *   TPat   -- Texture pattern struct
  145. *   
  146. * OUTPUT
  147. *   
  148. * RETURNS
  149. *
  150. *   DBL value exactly 0.0 or 1.0
  151. *   
  152. * AUTHOR
  153. *
  154. *   Dan Farmer
  155. *   
  156. * DESCRIPTION
  157. *
  158. * CHANGES
  159. *   Oct 1994    : adapted from pigment by [CY]
  160. *
  161. ******************************************************************************/
  162.  
  163. static DBL brick (EPoint, TPat)
  164. VECTOR EPoint;
  165. TPATTERN *TPat;
  166. {
  167.   int ibrickx, ibricky, ibrickz;
  168.   DBL brickheight, brickwidth, brickdepth;
  169.   DBL brickmortar, mortarheight, mortarwidth, mortardepth;
  170.   DBL brickx, bricky, brickz;
  171.   DBL x, y, z, fudgit;
  172.  
  173.   fudgit=Small_Tolerance+TPat->Vals.Brick.Mortar;
  174.  
  175.   x =  EPoint[X]+fudgit;
  176.   y =  EPoint[Y]+fudgit;
  177.   z =  EPoint[Z]+fudgit;
  178.  
  179.   brickwidth  = TPat->Vals.Brick.Size[X];
  180.   brickheight = TPat->Vals.Brick.Size[Y];
  181.   brickdepth  = TPat->Vals.Brick.Size[Z];
  182.   brickmortar = (DBL)TPat->Vals.Brick.Mortar;
  183.  
  184.   mortarwidth  = brickmortar / brickwidth;
  185.   mortarheight = brickmortar / brickheight;
  186.   mortardepth  = brickmortar / brickdepth;
  187.  
  188.   /* 1) Check mortar layers in the X-Z plane (ie: top view) */
  189.  
  190.   bricky = y / brickheight;
  191.   ibricky = (int) bricky;
  192.   bricky -= (DBL) ibricky;
  193.  
  194.   if (bricky < 0.0)
  195.   {
  196.     bricky += 1.0;
  197.   }
  198.  
  199.   if (bricky <= mortarheight)
  200.   {
  201.     return(0.0);
  202.   }
  203.  
  204.   bricky = (y / brickheight) * 0.5;
  205.   ibricky = (int) bricky;
  206.   bricky -= (DBL) ibricky;
  207.  
  208.   if (bricky < 0.0)
  209.   {
  210.     bricky += 1.0;
  211.   }
  212.  
  213.  
  214.   /* 2) Check ODD mortar layers in the Y-Z plane (ends) */
  215.  
  216.   brickx = (x / brickwidth);
  217.   ibrickx = (int) brickx;
  218.   brickx -= (DBL) ibrickx;
  219.  
  220.   if (brickx < 0.0)
  221.   {
  222.     brickx += 1.0;
  223.   }
  224.  
  225.   if ((brickx <= mortarwidth) && (bricky <= 0.5))
  226.   {
  227.     return(0.0);
  228.   }
  229.  
  230.   /* 3) Check EVEN mortar layers in the Y-Z plane (ends) */
  231.  
  232.   brickx = (x / brickwidth) + 0.5;
  233.   ibrickx = (int) brickx;
  234.   brickx -= (DBL) ibrickx;
  235.  
  236.   if (brickx < 0.0)
  237.   {
  238.     brickx += 1.0;
  239.   }
  240.  
  241.   if ((brickx <= mortarwidth) && (bricky > 0.5))
  242.   {
  243.     return(0.0);
  244.   }
  245.  
  246.   /* 4) Check ODD mortar layers in the Y-X plane (facing) */
  247.  
  248.   brickz = (z / brickdepth);
  249.   ibrickz = (int) brickz;
  250.   brickz -= (DBL) ibrickz;
  251.  
  252.   if (brickz < 0.0)
  253.   {
  254.     brickz += 1.0;
  255.   }
  256.  
  257.   if ((brickz <= mortardepth) && (bricky > 0.5))
  258.   {
  259.     return(0.0);
  260.   }
  261.  
  262.   /* 5) Check EVEN mortar layers in the X-Y plane (facing) */
  263.  
  264.   brickz = (z / brickdepth) + 0.5;
  265.   ibrickz = (int) brickz;
  266.   brickz -= (DBL) ibrickz;
  267.  
  268.   if (brickz < 0.0)
  269.   {
  270.     brickz += 1.0;
  271.   }
  272.  
  273.   if ((brickz <= mortardepth) && (bricky <= 0.5))
  274.   {
  275.     return(0.0);
  276.   }
  277.  
  278.   /* If we've gotten this far, color me brick. */
  279.  
  280.   return(1.0);
  281. }
  282.  
  283.  
  284. /*****************************************************************************
  285. *
  286. * FUNCTION
  287. *
  288. *   checker
  289. *
  290. * INPUT
  291. *
  292. *   EPoint -- The point in 3d space at which the pattern
  293. *   is evaluated.
  294. *
  295. * OUTPUT
  296. *
  297. * RETURNS
  298. *
  299. *   DBL value exactly 0.0 or 1.0
  300. *
  301. * AUTHOR
  302. *
  303. *   POV-Team
  304. *
  305. * DESCRIPTION
  306. *
  307. * CHANGES
  308. *   Oct 1994    : adapted from pigment by [CY]
  309. *
  310. ******************************************************************************/
  311.  
  312. static DBL checker (EPoint)
  313. VECTOR EPoint;
  314. {
  315.   int value;
  316.  
  317.   value = (int)(floor(EPoint[X]+Small_Tolerance) +
  318.                 floor(EPoint[Y]+Small_Tolerance) +
  319.                 floor(EPoint[Z]+Small_Tolerance));
  320.  
  321.   if (value & 1)
  322.   {
  323.     return (1.0);
  324.   }
  325.   else
  326.   {
  327.     return (0.0);
  328.   }
  329. }
  330.  
  331.  
  332.  
  333. /*****************************************************************************
  334. *
  335. * FUNCTION
  336. *
  337. *   crackle
  338. *
  339. * INPUT
  340. *
  341. *   EPoint -- The point in 3d space at which the pattern
  342. *   is evaluated.
  343. * OUTPUT
  344. *
  345. * RETURNS
  346. *
  347. *   DBL value in the range 0.0 to 1.0
  348. *
  349. * AUTHOR
  350. *
  351. *   Jim McElhiney
  352. *
  353. * DESCRIPTION
  354. *
  355. *   "crackle":
  356. *
  357. *   New colour function by Jim McElhiney,
  358. *     CompuServe 71201,1326, aka mcelhiney@acm.org
  359. *
  360. *   Large scale, without turbulence, makes a pretty good stone wall.
  361. *   Small scale, without turbulence, makes a pretty good crackle ceramic glaze.
  362. *   Highly turbulent (with moderate displacement) makes a good marble, solving
  363. *   the problem of apparent parallel layers in Perlin's method.
  364. *   2 octaves of full-displacement turbulence make a great "drizzled paint"
  365. *   pattern, like a 1950's counter top.
  366. *   Rule of thumb:  put a single colour transition near 0 in your colour map.
  367. *
  368. *   Mathematically, the set crackle(p)=0 is a 3D Voronoi diagram of a field of
  369. *   semirandom points, and crackle(p)>0 is distance from set along shortest path.
  370. *   (A Voronoi diagram is the locus of points equidistant from their 2 nearest
  371. *   neighbours from a set of disjoint points, like the membranes in suds are
  372. *   to the centres of the bubbles).
  373. *
  374. *   All "crackle" specific source code and examples are in the public domain.
  375. *
  376. * CHANGES
  377. *   Oct 1994    : adapted from pigment by [CY]
  378. *
  379. ******************************************************************************/
  380.  
  381. static DBL crackle (EPoint)
  382. VECTOR EPoint;
  383. {
  384.   int    i;
  385.   long   thisseed;
  386.   DBL    sum, minsum, minsum2, tf;
  387.   VECTOR sv, tv, dv, t1, add;
  388.  
  389.   static int cvc;
  390.   static long lastseed = 0x80000000;
  391.   static VECTOR cv[81];
  392.  
  393.   Assign_Vector(tv,EPoint);
  394.  
  395.   /*
  396.    * Check to see if the input point is in the same unit cube as the last
  397.    * call to this function, to use cache of cubelets for speed.
  398.    */
  399.  
  400.   thisseed = PickInCube(tv, t1);
  401.  
  402.   if (thisseed != lastseed)
  403.   {
  404.     /*
  405.      * No, not same unit cube.  Calculate the random points for this new
  406.      * cube and its 80 neighbours which differ in any axis by 1 or 2.
  407.      * Why distance of 2?  If there is 1 point in each cube, located
  408.      * randomly, it is possible for the closest random point to be in the
  409.      * cube 2 over, or the one two over and one up.  It is NOT possible
  410.      * for it to be two over and two up.  Picture a 3x3x3 cube with 9 more
  411.      * cubes glued onto each face.
  412.      */
  413.  
  414.     /* Now store a points for this cube and each of the 80 neighbour cubes. */
  415.  
  416.     cvc = 0;
  417.  
  418.     for (add[X] = -2.0; add[X] < 2.5; add[X] +=1.0)
  419.     {
  420.       for (add[Y] = -2.0; add[Y] < 2.5; add[Y] += 1.0)
  421.       {
  422.         for (add[Z] = -2.0; add[Z] < 2.5; add[Z] += 1.0)
  423.         {
  424.           /* For each cubelet in a 5x5 cube. */
  425.  
  426.           if ((fabs(add[X])>1.5)+(fabs(add[Y])>1.5)+(fabs(add[Z])>1.5) <= 1.0)
  427.           {
  428.             /* Yes, it's within a 3d knight move away. */
  429.  
  430.             VAdd(sv, tv, add);
  431.  
  432.             PickInCube(sv, t1);
  433.  
  434.             cv[cvc][X] = t1[X];
  435.             cv[cvc][Y] = t1[Y];
  436.             cv[cvc][Z] = t1[Z];
  437.             cvc++;
  438.           }
  439.         }
  440.       }
  441.     }
  442.  
  443.     lastseed = thisseed;
  444.   }
  445.  
  446.   /*
  447.    * Find the 2 points with the 2 shortest distances from the input point.
  448.    * Loop invariant:  minsum is shortest dist, minsum2 is 2nd shortest
  449.    */
  450.  
  451.   /* Set up the loop so the invariant is true:  minsum <= minsum2 */
  452.  
  453.   VSub(dv, cv[0], tv);  minsum  = VSumSqr(dv);
  454.   VSub(dv, cv[1], tv);  minsum2 = VSumSqr(dv);
  455.  
  456.   if (minsum2 < minsum)
  457.   {
  458.     tf = minsum; minsum = minsum2; minsum2 = tf;
  459.   }
  460.  
  461.   /* Loop for the 81 cubelets to find closest and 2nd closest. */
  462.  
  463.   for (i = 2; i < cvc; i++)
  464.   {
  465.     VSub(dv, cv[i], tv);
  466.  
  467.     sum = VSumSqr(dv);
  468.  
  469.     if (sum < minsum)
  470.     {
  471.       minsum2 = minsum;
  472.       minsum = sum;
  473.     }
  474.     else
  475.     {
  476.       if (sum < minsum2)
  477.       {
  478.         minsum2 = sum;
  479.       }
  480.     }
  481.   }
  482.  
  483.   /* Crackle value is absolute value of diff in dist to closest 2 points. */
  484.  
  485.   tf = sqrt(minsum2) - sqrt(minsum);      /* minsum is known <= minsum2 */
  486.  
  487.   /*
  488.    * Note that the theoretical range of this function is 0 to root 3.
  489.    * In practice, it rarely exceeds 0.9, and only very rarely 1.0
  490.    */
  491.  
  492.   return min(tf, 1.);
  493. }
  494.  
  495.  
  496. /*****************************************************************************
  497. *
  498. * FUNCTION
  499. *
  500. *   gradient
  501. *
  502. * INPUT
  503. *
  504. *   EPoint -- The point in 3d space at which the pattern
  505. *   is evaluated.
  506. *   
  507. * OUTPUT
  508. *   
  509. * RETURNS
  510. *
  511. *   DBL value in the range 0.0 to 1.0
  512. *   
  513. * AUTHOR
  514. *
  515. *   POV-Ray Team
  516. *   
  517. * DESCRIPTION
  518. *
  519. *   Gradient Pattern - gradient based on the fractional values of
  520. *   x, y or z, based on whether or not the given directional vector is
  521. *   a 1.0 or a 0.0.
  522. *   The basic concept of this is from DBW Render, but Dave Wecker's
  523. *   only supports simple Y axis gradients.
  524. *
  525. * CHANGES
  526. *   Oct 1994    : adapted from pigment by [CY]
  527. *
  528. ******************************************************************************/
  529.  
  530. static DBL gradient (EPoint, TPat)
  531. VECTOR EPoint;
  532. TPATTERN *TPat;
  533. {
  534.   register int i;
  535.   register DBL temp;
  536.   DBL value = 0.0;
  537.  
  538.   for (i=X; i<=Z; i++)
  539.   {
  540.     if (TPat->Vals.Gradient[i] != 0.0)
  541.     {
  542.       temp = fabs(EPoint[i]);
  543.  
  544.       value += fmod(temp,1.0);
  545.     }
  546.   }
  547.  
  548.   /* Clamp to 1.0. */
  549.  
  550.   value = ((value > 1.0) ? fmod(value, 1.0) : value);
  551.  
  552.   return(value);
  553. }
  554.  
  555.  
  556.  
  557. /*****************************************************************************
  558. *
  559. * FUNCTION
  560. *
  561. *   granite
  562. *
  563. * INPUT
  564. *
  565. *   EPoint -- The point in 3d space at which the pattern
  566. *   is evaluated.
  567. *   
  568. * OUTPUT
  569. *   
  570. * RETURNS
  571. *
  572. *   DBL value in the range 0.0 to 1.0
  573. *   
  574. * AUTHOR
  575. *
  576. *   POV-Ray Team
  577. *   
  578. * DESCRIPTION
  579. *
  580. *   Granite - kind of a union of the "spotted" and the "dented" textures,
  581. *   using a 1/f fractal noise function for color values. Typically used
  582. *   with small scaling values. Should work with colour maps for pink granite.
  583. *
  584. * CHANGES
  585. *   Oct 1994    : adapted from pigment by [CY]
  586. *
  587. ******************************************************************************/
  588.  
  589. static DBL granite (EPoint)
  590. VECTOR EPoint;
  591. {
  592.   register int i;
  593.   register DBL temp, noise = 0.0, freq = 1.0;
  594.   VECTOR tv1,tv2;
  595.  
  596.   VScale(tv1,EPoint,4.0);
  597.  
  598.   for (i = 0; i < 6 ; freq *= 2.0, i++)
  599.   {
  600.     VScale(tv2,tv1,freq);
  601.     temp = 0.5 - Noise (tv2);
  602.  
  603.     temp = fabs(temp);
  604.  
  605.     noise += temp / freq;
  606.   }
  607.  
  608.   return(noise);
  609. }
  610.  
  611.  
  612.  
  613. /*****************************************************************************
  614. *
  615. * FUNCTION
  616. *
  617. *   leopard
  618. *
  619. * INPUT
  620. *
  621. *   EPoint -- The point in 3d space at which the pattern
  622. *   is evaluated.
  623. *
  624. * OUTPUT
  625. *
  626. * RETURNS
  627. *
  628. *   DBL value in the range 0.0 to 1.0
  629. *
  630. * AUTHOR
  631. *
  632. *   Scott Taylor
  633. *
  634. * DESCRIPTION
  635. *
  636. * CHANGES
  637. *   Jul 1991 : Creation.
  638. *   Oct 1994 : adapted from pigment by [CY]
  639. *
  640. ******************************************************************************/
  641.  
  642. static DBL leopard (EPoint)
  643. VECTOR EPoint;
  644. {
  645.   register DBL value, temp1, temp2, temp3;
  646.  
  647.   /* This form didn't work with Zortech 386 compiler */
  648.   /* value = Sqr((sin(x)+sin(y)+sin(z))/3); */
  649.   /* So we break it down. */
  650.  
  651.   temp1 = sin(EPoint[X]);
  652.   temp2 = sin(EPoint[Y]);
  653.   temp3 = sin(EPoint[Z]);
  654.  
  655.   value = Sqr((temp1 + temp2 + temp3) / 3.0);
  656.  
  657.   return(value);
  658. }
  659.  
  660.  
  661.  
  662. /*****************************************************************************
  663. *
  664. * FUNCTION
  665. *
  666. *   mandel
  667. *
  668. * INPUT
  669. *
  670. *   EPoint -- The point in 3d space at which the pattern
  671. *   is evaluated.
  672. *
  673. * OUTPUT
  674. *
  675. * RETURNS
  676. *
  677. *   DBL value in the range 0.0 to 1.0
  678. *
  679. * AUTHOR
  680. *
  681. *   submitted by user, name lost (sorry)
  682. *
  683. * DESCRIPTION
  684. * The mandel pattern computes the standard Mandelbrot fractal pattern and
  685. * projects it onto the X-Y plane.  It uses the X and Y coordinates to compute
  686. * the Mandelbrot set.
  687. *
  688. * CHANGES
  689. *   Oct 1994 : adapted from pigment by [CY]
  690. *
  691. ******************************************************************************/
  692.  
  693. static DBL mandel (EPoint, TPat)
  694. VECTOR EPoint;
  695. TPATTERN *TPat;
  696. {
  697.   int it_max, col;
  698.   DBL a, b, cf, a2, b2, x, y;
  699.  
  700.   a = x = EPoint[X]; a2 = Sqr(a);
  701.   b = y = EPoint[Y]; b2 = Sqr(b);
  702.  
  703.   it_max = TPat->Vals.Iterations;
  704.  
  705.   for (col = 0; col < it_max; col++)
  706.   {
  707.     b  = 2.0 * a * b + y;
  708.     a  = a2 - b2 + x;
  709.  
  710.     a2 = Sqr(a);
  711.     b2 = Sqr(b);
  712.  
  713.     if ((a2 + b2) > 4.0)
  714.     {
  715.       break;
  716.     }
  717.   }
  718.  
  719.   cf = (DBL)col / (DBL)it_max;
  720.  
  721.   return(cf);
  722. }
  723.  
  724.  
  725.  
  726. /*****************************************************************************
  727. *
  728. * FUNCTION
  729. *
  730. *   marble
  731. *
  732. * INPUT
  733. *
  734. *   EPoint -- The point in 3d space at which the pattern
  735. *   is evaluated.
  736. *   TPat   -- Texture pattern struct
  737. *
  738. * OUTPUT
  739. *
  740. * RETURNS
  741. *
  742. *   DBL value in the range 0.0 to 1.0
  743. *
  744. * AUTHOR
  745. *
  746. *   POV-Ray Team
  747. *
  748. * DESCRIPTION
  749. *
  750. * CHANGES
  751. *   Oct 1994 : adapted from pigment by [CY]
  752. *
  753. ******************************************************************************/
  754.  
  755. static DBL marble (EPoint, TPat)
  756. VECTOR EPoint;
  757. TPATTERN *TPat;
  758. {
  759.   register DBL turb_val;
  760.   TURB *Turb;
  761.  
  762.   if ((Turb=Search_For_Turb(TPat->Warps)) != NULL)
  763.   {
  764.     turb_val = Turb->Turbulence[X] * Turbulence(EPoint,Turb);
  765.   }
  766.   else
  767.   {
  768.     turb_val = 0.0;
  769.   }
  770.  
  771.   return(EPoint[X] + turb_val);
  772. }
  773.  
  774.  
  775.  
  776. /*****************************************************************************
  777. *
  778. * FUNCTION
  779. *
  780. *   onion
  781. *
  782. * INPUT
  783. *
  784. *   EPoint -- The point in 3d space at which the pattern
  785. *   is evaluated.
  786. *
  787. * OUTPUT
  788. *
  789. * RETURNS
  790. *
  791. *   DBL value in the range 0.0 to 1.0
  792. *
  793. * AUTHOR
  794. *
  795. *   Scott Taylor
  796. *
  797. * DESCRIPTION
  798. *
  799. * CHANGES
  800. *   Jul 1991 : Creation.
  801. *   Oct 1994 : adapted from pigment by [CY]
  802. *
  803. ******************************************************************************/
  804.  
  805. static DBL onion (EPoint)
  806. VECTOR EPoint;
  807. {
  808.   /* The variable noise is not used as noise in this function */
  809.  
  810.   register DBL noise;
  811.  
  812. /*
  813.    This ramp goes 0-1,1-0,0-1,1-0...
  814.  
  815.    noise = (fmod(sqrt(Sqr(x)+Sqr(y)+Sqr(z)),2.0)-1.0);
  816.  
  817.    if (noise<0.0) {noise = 0.0-noise;}
  818. */
  819.  
  820.   /* This ramp goes 0-1, 0-1, 0-1, 0-1 ... */
  821.  
  822.   noise = (fmod(sqrt(Sqr(EPoint[X])+Sqr(EPoint[Y])+Sqr(EPoint[Z])), 1.0));
  823.  
  824.   return(noise);
  825. }
  826.  
  827.  
  828.  
  829. /*****************************************************************************
  830. *
  831. * FUNCTION
  832. *
  833. *   radial
  834. *
  835. * INPUT
  836. *
  837. *   EPoint -- The point in 3d space at which the pattern
  838. *   is evaluated.
  839. *
  840. * OUTPUT
  841. *
  842. * RETURNS
  843. *
  844. *   DBL value in the range 0.0 to 1.0
  845. *
  846. * AUTHOR
  847. *
  848. *   Chris Young -- new in vers 2.0
  849. *
  850. * DESCRIPTION
  851. *
  852. * CHANGES
  853. *   Oct 1994 : adapted from pigment by [CY]
  854. *
  855. ******************************************************************************/
  856.  
  857. static DBL radial (EPoint)
  858. VECTOR EPoint;
  859. {
  860.   register DBL value;
  861.  
  862.   if ((fabs(EPoint[X])<0.001) && (fabs(EPoint[Z])<0.001))
  863.   {
  864.     value = 0.25;
  865.   }
  866.   else
  867.   {
  868.     value = 0.25 + (atan2(EPoint[X],EPoint[Z]) + M_PI) / (2.0 * M_PI);
  869.   }
  870.  
  871.   return(value);
  872. }
  873.  
  874.  
  875.  
  876. /*****************************************************************************
  877. *
  878. * FUNCTION
  879. *
  880. *   spiral1
  881. *
  882. * INPUT
  883. *
  884. *   EPoint -- The point in 3d space at which the pattern
  885. *   is evaluated.
  886. *   TPat   -- Texture pattern struct
  887. *
  888. * OUTPUT
  889. *
  890. * RETURNS
  891. *
  892. *   DBL value in the range 0.0 to 1.0
  893. *
  894. * AUTHOR
  895. *
  896. *   Dieter Bayer
  897. *
  898. * DESCRIPTION
  899. *   Spiral whirles around z-axis.
  900. *   The number of "arms" is defined in the TPat.
  901. *
  902. * CHANGES
  903. *   Aug 1994 : Creation.
  904. *   Oct 1994 : adapted from pigment by [CY]
  905. *
  906. ******************************************************************************/
  907.  
  908. static DBL spiral1(EPoint, TPat)
  909. VECTOR EPoint;
  910. TPATTERN *TPat;
  911. {
  912.   DBL rad, phi, turb_val;
  913.   DBL x = EPoint[X];
  914.   DBL y = EPoint[Y];
  915.   DBL z = EPoint[Z];
  916.   TURB *Turb;
  917.  
  918.   if ((Turb=Search_For_Turb(TPat->Warps)) != NULL)
  919.   {
  920.     turb_val = Turb->Turbulence[X] * Turbulence(EPoint,Turb);
  921.   }
  922.   else
  923.   {
  924.     turb_val = 0.0;
  925.   }
  926.  
  927.   /* Get distance from z-axis. */
  928.  
  929.   rad = sqrt(x * x + y * y);
  930.  
  931.   /* Get angle in x,y-plane (0...2 PI). */
  932.  
  933.   if (rad == 0.0)
  934.   {
  935.     phi = 0.0;
  936.   }
  937.   else
  938.   {
  939.     if (x < 0.0)
  940.     {
  941.       phi = 1.5 * M_PI - asin(y / rad);
  942.     }
  943.     else
  944.     {
  945.       phi = 0.5 * M_PI + asin(y / rad);
  946.     }
  947.   }
  948.  
  949.   return(z + rad + (DBL)TPat->Vals.Arms * phi / (2.0 * M_PI) + turb_val);
  950. }
  951.  
  952.  
  953.  
  954. /*****************************************************************************
  955. *
  956. * FUNCTION
  957. *
  958. *   spiral2
  959. *
  960. * INPUT
  961. *
  962. *   EPoint -- The point in 3d space at which the pattern
  963. *   is evaluated.
  964. *   TPat   -- Texture pattern struct
  965. *
  966. * OUTPUT
  967. *
  968. * RETURNS
  969. *
  970. *   DBL value in the range 0.0 to 1.0
  971. *
  972. * AUTHOR
  973. *
  974. *   Dieter Bayer
  975. *
  976. * DESCRIPTION
  977. *   Spiral whirles around z-axis.
  978. *   The number of "arms" is defined in the TPat.
  979. *
  980. * CHANGES
  981. *   Aug 1994 : Creation.
  982. *   Oct 1994 : adapted from pigment by [CY]
  983. *
  984. ******************************************************************************/
  985.  
  986.  
  987. static DBL spiral2(EPoint, TPat)
  988. VECTOR EPoint;
  989. TPATTERN *TPat;
  990. {
  991.   DBL rad, phi, turb_val;
  992.   DBL x = EPoint[X];
  993.   DBL y = EPoint[Y];
  994.   DBL z = EPoint[Z];
  995.   TURB *Turb;
  996.  
  997.   if ((Turb=Search_For_Turb(TPat->Warps)) != NULL)
  998.   {
  999.     turb_val = Turb->Turbulence[X] * Turbulence(EPoint,Turb);
  1000.   }
  1001.   else
  1002.   {
  1003.     turb_val = 0.0;
  1004.   }
  1005.  
  1006.   /* Get distance from z-axis. */
  1007.  
  1008.   rad = sqrt(x * x + y * y);
  1009.  
  1010.   /* Get angle in x,y-plane (0...2 PI) */
  1011.  
  1012.   if (rad == 0.0)
  1013.   {
  1014.     phi = 0.0;
  1015.   }
  1016.   else
  1017.   {
  1018.     if (x < 0.0)
  1019.     {
  1020.       phi = 1.5 * M_PI - asin(y / rad);
  1021.     }
  1022.     else
  1023.     {
  1024.       phi = 0.5 * M_PI + asin(y / rad);
  1025.     }
  1026.   }
  1027.  
  1028.   turb_val = Triangle_Wave(z + rad + (DBL)TPat->Vals.Arms * phi / (2.0 * M_PI) + turb_val);
  1029.  
  1030.   return(Triangle_Wave(rad) + turb_val);
  1031. }
  1032.  
  1033.  
  1034.  
  1035. /*****************************************************************************
  1036. *
  1037. * FUNCTION
  1038. *
  1039. *   wood
  1040. *
  1041. * INPUT
  1042. *
  1043. *   EPoint -- The point in 3d space at which the pattern
  1044. *   is evaluated.
  1045. *   TPat   -- Texture pattern struct
  1046. *
  1047. * OUTPUT
  1048. *
  1049. * RETURNS
  1050. *
  1051. *   DBL value in the range 0.0 to 1.0
  1052. *
  1053. * AUTHOR
  1054. *
  1055. *   POV-Ray Team
  1056. *
  1057. * DESCRIPTION
  1058. *
  1059. * CHANGES
  1060. *   Oct 1994 : adapted from pigment by [CY]
  1061. *
  1062. ******************************************************************************/
  1063.  
  1064.  
  1065. static DBL wood (EPoint, TPat)
  1066. VECTOR EPoint;
  1067. TPATTERN *TPat;
  1068. {
  1069.   register DBL length;
  1070.   VECTOR WoodTurbulence;
  1071.   VECTOR point;
  1072.   DBL x=EPoint[X];
  1073.   DBL y=EPoint[Y];
  1074.   TURB *Turb;
  1075.  
  1076.   if ((Turb=Search_For_Turb(TPat->Warps)) != NULL)
  1077.   {
  1078.     DTurbulence (WoodTurbulence, EPoint,Turb);
  1079.     point[X] = cycloidal((x + WoodTurbulence[X]) * Turb->Turbulence[X]);
  1080.     point[Y] = cycloidal((y + WoodTurbulence[Y]) * Turb->Turbulence[Y]);
  1081.   }
  1082.   else
  1083.   {
  1084.     point[X] = 0.0;
  1085.     point[Y] = 0.0;
  1086.   }
  1087.   point[Z] = 0.0;
  1088.  
  1089.   point[X] += x;
  1090.   point[Y] += y;
  1091.  
  1092.   /* point[Z] += z; Deleted per David Buck --  BP 7/91 */
  1093.  
  1094.   VLength (length, point);
  1095.  
  1096.   return(length);
  1097. }
  1098.  
  1099.  
  1100. /*****************************************************************************
  1101. *
  1102. * FUNCTION
  1103. *
  1104. *   hexagon
  1105. *
  1106. * INPUT
  1107. *
  1108. *   EPoint -- The point in 3d space at which the pattern
  1109. *   is evaluated.
  1110. *
  1111. * OUTPUT
  1112. *
  1113. * RETURNS
  1114. *
  1115. *   DBL value exactly 0.0, 1.0 or 2.0
  1116. *
  1117. * AUTHOR
  1118. *
  1119. *   Ernest MacDougal Campbell III
  1120. *   
  1121. * DESCRIPTION
  1122. *
  1123. *   TriHex pattern -- Ernest MacDougal Campbell III (EMC3) 11/23/92
  1124. *
  1125. *   Creates a hexagon pattern in the XZ plane.
  1126. *
  1127. *   This algorithm is hard to explain.  First it scales the point to make
  1128. *   a few of the later calculations easier, then maps some points to be
  1129. *   closer to the Origin.  A small area in the first quadrant is subdivided
  1130. *   into a 6 x 6 grid.  The position of the point mapped into that grid
  1131. *   determines its color.  For some points, just the grid location is enough,
  1132. *   but for others, we have to calculate which half of the block it's in
  1133. *   (this is where the atan2() function comes in handy).
  1134. *
  1135. * CHANGES
  1136. *   Nov 1992 : Creation.
  1137. *   Oct 1994 : adapted from pigment by [CY]
  1138. *
  1139. ******************************************************************************/
  1140.  
  1141. #define xfactor 0.5;         /* each triangle is split in half for the grid */
  1142. #define zfactor 0.866025404; /* sqrt(3)/2 -- Height of an equilateral triangle */
  1143.  
  1144. static DBL hexagon (EPoint)
  1145. VECTOR EPoint;
  1146. {
  1147.   int xm, zm;
  1148.   int brkindx;
  1149.   DBL xs, zs, xl, zl, value = 0.0;
  1150.   DBL x=EPoint[X];
  1151.   DBL z=EPoint[Z];
  1152.  
  1153.  
  1154.   /* Keep all numbers positive.  Also, if z is negative, map it in such a
  1155.    * way as to avoid mirroring across the x-axis.  The value 5.196152424
  1156.    * is (sqrt(3)/2) * 6 (because the grid is 6 blocks high)
  1157.    */
  1158.  
  1159.   x = fabs(x);
  1160.  
  1161.   /* Avoid mirroring across x-axis. */
  1162.  
  1163.   z = z < 0.0 ? 5.196152424 - fabs(z) : z;
  1164.  
  1165.   /* Scale point to make calcs easier. */
  1166.  
  1167.   xs = x/xfactor;
  1168.   zs = z/zfactor;
  1169.  
  1170.   /* Map points into the 6 x 6 grid where the basic formula works. */
  1171.  
  1172.   xs -= floor(xs/6.0) * 6.0;
  1173.   zs -= floor(zs/6.0) * 6.0;
  1174.  
  1175.   /* Get a block in the 6 x 6 grid. */
  1176.  
  1177.   xm = (int) FLOOR(xs) % 6;
  1178.   zm = (int) FLOOR(zs) % 6;
  1179.  
  1180.   switch (xm)
  1181.   {
  1182.     /* These are easy cases: Color depends only on xm and zm. */
  1183.  
  1184.     case 0:
  1185.     case 5:
  1186.  
  1187.       switch (zm)
  1188.       {
  1189.         case 0:
  1190.         case 5: value = 0; break;
  1191.  
  1192.         case 1:
  1193.         case 2: value = 1; break;
  1194.  
  1195.         case 3:
  1196.         case 4: value = 2; break;
  1197.       }
  1198.  
  1199.       break;
  1200.  
  1201.     case 2:
  1202.     case 3:
  1203.  
  1204.       switch (zm)
  1205.       {
  1206.         case 0:
  1207.         case 1: value = 2; break;
  1208.  
  1209.         case 2:
  1210.         case 3: value = 0; break;
  1211.  
  1212.         case 4:
  1213.         case 5: value = 1; break;
  1214.       }
  1215.  
  1216.       break;
  1217.  
  1218.     /* These cases are harder.  These blocks are divided diagonally
  1219.      * by the angled edges of the hexagons.  Some slope positive, and
  1220.      * others negative.  We flip the x value of the negatively sloped
  1221.      * pieces.  Then we check to see if the point in question falls
  1222.      * in the upper or lower half of the block.  That info, plus the
  1223.      * z status of the block determines the color.
  1224.      */
  1225.  
  1226.     case 1:
  1227.     case 4:
  1228.  
  1229.       /* Map the point into the block at the origin. */
  1230.  
  1231.       xl = xs-xm;
  1232.       zl = zs-zm;
  1233.  
  1234.       /* These blocks have negative slopes so we flip it horizontally. */
  1235.  
  1236.       if (((xm + zm) % 2) == 1)
  1237.       {
  1238.         xl = 1.0 - xl;
  1239.       }
  1240.  
  1241.       /* Avoid a divide-by-zero error. */
  1242.  
  1243.       if (xl == 0.0)
  1244.       {
  1245.         xl = 0.0001;
  1246.       }
  1247.  
  1248.       /* Is the angle less-than or greater-than 45 degrees? */
  1249.  
  1250.       brkindx = (zl / xl) < 1.0;
  1251.  
  1252.       /* was...
  1253.        * brkindx = (atan2(zl,xl) < (45 * M_PI/180));
  1254.        * ...but because of the mapping, it's easier and cheaper,
  1255.        * CPU-wise, to just use a good ol' slope.
  1256.        */
  1257.  
  1258.       switch (brkindx)
  1259.       {
  1260.         case TRUE:
  1261.  
  1262.           switch (zm)
  1263.           {
  1264.             case 0:
  1265.             case 3: value = 0; break;
  1266.  
  1267.             case 2:
  1268.             case 5: value = 1; break;
  1269.  
  1270.             case 1:
  1271.             case 4: value = 2; break;
  1272.           }
  1273.  
  1274.           break;
  1275.  
  1276.         case FALSE:
  1277.  
  1278.           switch (zm)
  1279.           {
  1280.             case 0:
  1281.             case 3: value = 2; break;
  1282.  
  1283.             case 2:
  1284.             case 5: value = 0; break;
  1285.  
  1286.             case 1:
  1287.             case 4: value = 1; break;
  1288.           }
  1289.  
  1290.           break;
  1291.       }
  1292.   }
  1293.  
  1294.   value = fmod(value, 3.0);
  1295.  
  1296.   return(value);
  1297. }
  1298.  
  1299.  
  1300.  
  1301. /*****************************************************************************
  1302. *
  1303. * FUNCTION
  1304. *
  1305. *   PickInCube(tv, p1)
  1306. *
  1307. * INPUT
  1308. *
  1309. *   ?
  1310. *
  1311. * OUTPUT
  1312. *   
  1313. * RETURNS
  1314. *
  1315. *   long integer hash function used, to speed up cacheing.
  1316. *   
  1317. * AUTHOR
  1318. *
  1319. *   Jim McElhiney
  1320. *   
  1321. * DESCRIPTION
  1322. *
  1323. *   A subroutine to go with crackle.
  1324. *
  1325. *   Pick a random point in the same unit-sized cube as tv, in a
  1326. *   predictable way, so that when called again with another point in
  1327. *   the same unit cube, p1 is picked to be the same.
  1328. *
  1329. * CHANGES
  1330. *
  1331. ******************************************************************************/
  1332.  
  1333. static long PickInCube(tv, p1)
  1334. VECTOR tv, p1;
  1335. {
  1336.   int seed;
  1337.   VECTOR flo;
  1338.  
  1339.   /*
  1340.    * This uses floor() not FLOOR, so it will not be a mirror
  1341.    * image about zero in the range -1.0 to 1.0. The viewer
  1342.    * won't see an artefact around the origin.
  1343.    */
  1344.  
  1345.   flo[X] = floor(tv[X] - EPSILON);
  1346.   flo[Y] = floor(tv[Y] - EPSILON);
  1347.   flo[Z] = floor(tv[Z] - EPSILON);
  1348.  
  1349.   seed = Hash3d((int)flo[X], (int)flo[Y], (int)flo[Z]);
  1350.  
  1351.   POV_SRAND(seed);
  1352.  
  1353.   p1[X] = flo[X] + FRAND();
  1354.   p1[Y] = flo[Y] + FRAND();
  1355.   p1[Z] = flo[Z] + FRAND();
  1356.  
  1357.   return((long)seed);
  1358. }
  1359.  
  1360.  
  1361.  
  1362. /*****************************************************************************
  1363. *
  1364. * FUNCTION
  1365. *
  1366. *   Evaluate_Pattern
  1367. *
  1368. * INPUT
  1369. *
  1370. *   EPoint -- The point in 3d space at which the pattern
  1371. *   is evaluated.
  1372. *   TPat   -- Texture pattern struct
  1373. *   
  1374. * OUTPUT
  1375. *   
  1376. * RETURNS
  1377. *
  1378. *   DBL result usual 0.0 to 1.0 but may be 2.0 in hexagon
  1379. *   
  1380. * AUTHOR
  1381. *
  1382. *   adapted from Add_Pigment by Chris Young
  1383. *   
  1384. * DESCRIPTION
  1385. *
  1386. * CHANGES
  1387. *
  1388. ******************************************************************************/
  1389.  
  1390. DBL Evaluate_TPat (TPat, EPoint)
  1391. TPATTERN *TPat;
  1392. VECTOR EPoint;
  1393. {
  1394.   DBL value = 0.0;
  1395.   VECTOR TPoint;
  1396.  
  1397.   Warp_EPoint (TPoint, EPoint, TPat);
  1398.  
  1399.   switch (TPat->Type)
  1400.   {
  1401.     case AGATE_PATTERN:    value = agate    (TPoint, TPat);   break;
  1402.  
  1403.     case BOZO_PATTERN:
  1404.     case SPOTTED_PATTERN:
  1405.     case BUMPS_PATTERN:    value = Noise    (TPoint);         break;
  1406.  
  1407.     case BRICK_PATTERN:    value = brick    (TPoint, TPat);   break;
  1408.     case CHECKER_PATTERN:  value = checker  (TPoint);         break;
  1409.     case CRACKLE_PATTERN:  value = crackle  (TPoint);         break;
  1410.     case GRADIENT_PATTERN: value = gradient (TPoint, TPat);   break;
  1411.     case GRANITE_PATTERN:  value = granite  (TPoint);         break;
  1412.     case HEXAGON_PATTERN:  value = hexagon  (TPoint);         break;
  1413.     case LEOPARD_PATTERN:  value = leopard  (TPoint);         break;
  1414.     case MANDEL_PATTERN:   value = mandel   (TPoint, TPat);   break;
  1415.     case MARBLE_PATTERN:   value = marble   (TPoint, TPat);   break;
  1416.     case ONION_PATTERN:    value = onion    (TPoint);         break;
  1417.     case RADIAL_PATTERN:   value = radial   (TPoint);         break;
  1418.     case SPIRAL1_PATTERN:  value = spiral1  (TPoint, TPat);   break;
  1419.     case SPIRAL2_PATTERN:  value = spiral2  (TPoint, TPat);   break;
  1420.     case PATTERN1_PATTERN: value = pattern1    (TPoint, TPat);   break;
  1421.     case PATTERN2_PATTERN: value = pattern2    (TPoint, TPat);   break;
  1422.     case PATTERN3_PATTERN: value = pattern3    (TPoint, TPat);   break;
  1423.     case WOOD_PATTERN:     value = wood     (TPoint, TPat);   break;
  1424.  
  1425.     case WAVES_PATTERN:    value = waves_pigm    (TPoint, TPat);   break;
  1426.     case RIPPLES_PATTERN:  value = ripples_pigm  (TPoint, TPat);   break;
  1427.     case WRINKLES_PATTERN: value = wrinkles_pigm (TPoint);   break;
  1428.     case DENTS_PATTERN:    value = dents_pigm    (TPoint);   break;
  1429.     case QUILTED_PATTERN:  value = quilted_pigm  (TPoint, TPat);   break;
  1430.     default: Error("Problem in Evaluate_TPat.");
  1431.   }
  1432.  
  1433.   if (TPat->Frequency !=0.0)
  1434.   {
  1435.     value = fmod(value * TPat->Frequency + TPat->Phase, 1.00001);
  1436.   }
  1437.  
  1438.   /* allow negative Frequency */
  1439.  
  1440.   if (value < 0.0)
  1441.   {
  1442.     value -= floor(value);
  1443.   }
  1444.  
  1445.   switch (TPat->Wave_Type)
  1446.   {
  1447.     case RAMP_WAVE:
  1448.       break;
  1449.  
  1450.     case SINE_WAVE:
  1451.       value = (1.0+cycloidal(value))*0.5;
  1452.       break;
  1453.  
  1454.     case TRIANGLE_WAVE:
  1455.       value = Triangle_Wave(value);
  1456.       break;
  1457.  
  1458.     case SCALLOP_WAVE:
  1459.       value = fabs(cycloidal(value*0.5));
  1460.       break;
  1461.  
  1462.     default: Error("Unknown Wave Type %d.",TPat->Wave_Type);
  1463.    }
  1464.  
  1465.   return(value);
  1466. }
  1467.  
  1468.  
  1469. /*****************************************************************************
  1470. *
  1471. * FUNCTION
  1472. *
  1473. * INPUT
  1474. *
  1475. * OUTPUT
  1476. *
  1477. * RETURNS
  1478. *
  1479. * AUTHOR
  1480. *
  1481. * DESCRIPTION
  1482. *
  1483. * CHANGES
  1484. *
  1485. ******************************************************************************/
  1486.  
  1487. void Init_TPat_Fields (Tpat)
  1488. TPATTERN *Tpat;
  1489. {
  1490.   Tpat->Type       = NO_PATTERN;
  1491.   Tpat->Wave_Type  = RAMP_WAVE;
  1492.   Tpat->Flags      = NO_FLAGS;
  1493.   Tpat->References = 1;
  1494.   Tpat->Frequency  = 1.0;
  1495.   Tpat->Phase      = 0.0;
  1496.   Tpat->Warps      = NULL;
  1497.   Tpat->Next       = NULL;
  1498.   Tpat->Blend_Map  = NULL;
  1499. }
  1500.  
  1501.  
  1502.  
  1503. /*****************************************************************************
  1504. *
  1505. * FUNCTION
  1506. *
  1507. * INPUT
  1508. *
  1509. * OUTPUT
  1510. *
  1511. * RETURNS
  1512. *
  1513. * AUTHOR
  1514. *
  1515. * DESCRIPTION
  1516. *
  1517. * CHANGES
  1518. *
  1519. ******************************************************************************/
  1520.  
  1521. void Copy_TPat_Fields (New, Old)
  1522. TPATTERN *New, *Old;
  1523. {
  1524.   *New = *Old;
  1525.   
  1526.   /* Copy warp chain */
  1527.   New->Warps = Copy_Warps(Old->Warps);
  1528.  
  1529.   New->Blend_Map = Copy_Blend_Map(Old->Blend_Map);
  1530.  
  1531.   /* Note, cannot copy Old->Next because we don't know what kind of
  1532.      thing this is.  It must be copied by Copy_Pigment, Copy_Tnormal etc.
  1533.   */
  1534.  
  1535.   if (Old->Type == BITMAP_PATTERN)
  1536.   {
  1537.      New->Vals.Image = Copy_Image(Old->Vals.Image);
  1538.   }
  1539. }
  1540.  
  1541.  
  1542.  
  1543. /*****************************************************************************
  1544. *
  1545. * FUNCTION
  1546. *
  1547. * INPUT
  1548. *
  1549. * OUTPUT
  1550. *
  1551. * RETURNS
  1552. *
  1553. * AUTHOR
  1554. *
  1555. * DESCRIPTION
  1556. *
  1557. * CHANGES
  1558. *
  1559. ******************************************************************************/
  1560.  
  1561. void Destroy_TPat_Fields(Tpat)
  1562. TPATTERN *Tpat;
  1563. {
  1564.   Destroy_Warps(Tpat->Warps);
  1565.   Destroy_Blend_Map(Tpat->Blend_Map);
  1566.   /* Note, cannot destroy Tpat->Next nor pattern itself because we don't
  1567.      know what kind of thing this is.  It must be destroied by Destroy_Pigment, etc.
  1568.   */
  1569.  
  1570.   if (Tpat->Type == BITMAP_PATTERN)
  1571.   {
  1572.      Destroy_Image(Tpat->Vals.Image);
  1573.   }
  1574. }
  1575.  
  1576.  
  1577.  
  1578.  
  1579. /*****************************************************************************
  1580. *
  1581. * FUNCTION
  1582. *
  1583. * INPUT
  1584. *
  1585. * OUTPUT
  1586. *
  1587. * RETURNS
  1588. *
  1589. * AUTHOR
  1590. *
  1591. * DESCRIPTION
  1592. *
  1593. * CHANGES
  1594. *
  1595. ******************************************************************************/
  1596.  
  1597. TURB *Create_Turb()
  1598. {
  1599.   TURB *New;
  1600.  
  1601.   New = POV_MALLOC(sizeof(TURB),"turbulence struct");
  1602.  
  1603.   Make_Vector(New->Turbulence, 0.0, 0.0, 0.0);
  1604.  
  1605.   New->Octaves = 6;
  1606.   New->Omega = 0.5;
  1607.   New->Lambda = 2.0;
  1608.  
  1609.   return(New);
  1610. }
  1611.  
  1612.  
  1613.  
  1614. /*****************************************************************************
  1615. *
  1616. * FUNCTION
  1617. *
  1618. * INPUT
  1619. *
  1620. * OUTPUT
  1621. *
  1622. * RETURNS
  1623. *
  1624. * AUTHOR
  1625. *
  1626. * DESCRIPTION
  1627. *
  1628. * CHANGES
  1629. *
  1630. ******************************************************************************/
  1631.  
  1632. #if 0   /* Unused function [AED] */
  1633. static TURB *Copy_Turb(Old)
  1634. TURB *Old;
  1635. {
  1636.   TURB *New;
  1637.  
  1638.   if (Old != NULL)
  1639.   {
  1640.     New = Create_Turb();
  1641.  
  1642.     *New = *Old;
  1643.   }
  1644.   else
  1645.   {
  1646.     New=NULL;
  1647.   }
  1648.  
  1649.   return(New);
  1650. }
  1651. #endif
  1652.  
  1653.  
  1654. /*****************************************************************************
  1655. *
  1656. * FUNCTION
  1657. *
  1658. *   Translate_Tpattern
  1659. *
  1660. * INPUT
  1661. *
  1662. * OUTPUT
  1663. *
  1664. * RETURNS
  1665. *
  1666. * AUTHOR
  1667. *
  1668. *   POV-Ray Team
  1669. *
  1670. * DESCRIPTION
  1671. *
  1672. * CHANGES
  1673. *
  1674. ******************************************************************************/
  1675.  
  1676. void Translate_Tpattern(Tpattern,Vector)
  1677. TPATTERN *Tpattern;
  1678. VECTOR Vector;
  1679. {
  1680.   TRANSFORM Trans;
  1681.  
  1682.   if (Tpattern != NULL)
  1683.   {
  1684.     Compute_Translation_Transform (&Trans, Vector);
  1685.  
  1686.     Transform_Tpattern (Tpattern, &Trans);
  1687.   }
  1688. }
  1689.  
  1690.  
  1691.  
  1692. /*****************************************************************************
  1693. *
  1694. * FUNCTION
  1695. *
  1696. *   Rotate_Tpattern
  1697. *
  1698. * INPUT
  1699. *
  1700. * OUTPUT
  1701. *
  1702. * RETURNS
  1703. *
  1704. * AUTHOR
  1705. *
  1706. *   POV-Ray Team
  1707. *
  1708. * DESCRIPTION
  1709. *
  1710. * CHANGES
  1711. *
  1712. ******************************************************************************/
  1713.  
  1714. void Rotate_Tpattern(Tpattern,Vector)
  1715. TPATTERN *Tpattern;
  1716. VECTOR Vector;
  1717. {
  1718.   TRANSFORM Trans;
  1719.  
  1720.   if (Tpattern != NULL)
  1721.   {
  1722.     Compute_Rotation_Transform (&Trans, Vector);
  1723.  
  1724.     Transform_Tpattern (Tpattern, &Trans);
  1725.   }
  1726. }
  1727.  
  1728.  
  1729.  
  1730. /*****************************************************************************
  1731. *
  1732. * FUNCTION
  1733. *
  1734. *   Scale_Tpattern
  1735. *
  1736. * INPUT
  1737. *
  1738. * OUTPUT
  1739. *
  1740. * RETURNS
  1741. *
  1742. * AUTHOR
  1743. *
  1744. *   POV-Ray Team
  1745. *
  1746. * DESCRIPTION
  1747. *
  1748. * CHANGES
  1749. *
  1750. ******************************************************************************/
  1751.  
  1752. void Scale_Tpattern(Tpattern,Vector)
  1753. TPATTERN *Tpattern;
  1754. VECTOR Vector;
  1755. {
  1756.   TRANSFORM Trans;
  1757.  
  1758.   if (Tpattern != NULL)
  1759.   {
  1760.     Compute_Scaling_Transform (&Trans, Vector);
  1761.  
  1762.     Transform_Tpattern (Tpattern, &Trans);
  1763.   }
  1764. }
  1765.  
  1766.  
  1767.  
  1768. /*****************************************************************************
  1769. *
  1770. * FUNCTION
  1771. *
  1772. *   Transform_Tpattern
  1773. *
  1774. * INPUT
  1775. *
  1776. * OUTPUT
  1777. *
  1778. * RETURNS
  1779. *
  1780. * AUTHOR
  1781. *
  1782. *   POV-Ray Team
  1783. *
  1784. * DESCRIPTION
  1785. *
  1786. * CHANGES
  1787. *
  1788. ******************************************************************************/
  1789.  
  1790. void Transform_Tpattern(Tpattern,Trans)
  1791. TPATTERN *Tpattern;
  1792. TRANSFORM *Trans;
  1793. {
  1794.   WARP *Temp;
  1795.  
  1796.   if (Tpattern != NULL)
  1797.   {
  1798.     if (Tpattern->Warps == NULL)
  1799.     {
  1800.       Tpattern->Warps=Create_Warp(TRANSFORM_WARP);
  1801.     }
  1802.     else
  1803.     {
  1804.       if (Tpattern->Warps->Warp_Type != TRANSFORM_WARP)
  1805.       {
  1806.         Temp=Tpattern->Warps;
  1807.  
  1808.         Tpattern->Warps=Create_Warp(TRANSFORM_WARP);
  1809.  
  1810.         Tpattern->Warps->Next_Warp=Temp;
  1811.       }
  1812.     }
  1813.  
  1814.     Compose_Transforms (&( ((TRANS *)(Tpattern->Warps))->Trans), Trans);
  1815.   }
  1816. }
  1817.  
  1818.  
  1819. /*****************************************************************************
  1820. *
  1821. * FUNCTION
  1822. *
  1823. *   ripples_pigm
  1824. *
  1825. * INPUT
  1826. *
  1827. *   EPoint -- The point in 3d space at which the pattern
  1828. *   is evaluated.
  1829. *   TPat   -- Texture pattern struct
  1830. *
  1831. * OUTPUT
  1832. *   
  1833. * RETURNS
  1834. *
  1835. *   DBL value in the range 0.0 to 1.0
  1836. *   
  1837. * AUTHOR
  1838. *
  1839. *   POV-Ray Team
  1840. *
  1841. * DESCRIPTION   : Note this pattern is only used for pigments and textures.
  1842. *                 Normals have a specialized pattern for this.
  1843. *
  1844. * CHANGES
  1845. *   Nov 1994 : adapted from normal by [CY]
  1846. *
  1847. ******************************************************************************/
  1848.  
  1849. static DBL ripples_pigm (EPoint, TPat)
  1850. VECTOR EPoint;
  1851. TPATTERN *TPat;
  1852. {
  1853.   register unsigned int i;
  1854.   register DBL length, index;
  1855.   DBL scalar =0.0;
  1856.   VECTOR point;
  1857.  
  1858.   for (i = 0 ; i < Number_Of_Waves ; i++)
  1859.   {
  1860.     VSub (point, EPoint, Wave_Sources[i]);
  1861.     VLength (length, point);
  1862.  
  1863.     if (length == 0.0)
  1864.       length = 1.0;
  1865.  
  1866.     index = length * TPat->Frequency + TPat->Phase;
  1867.  
  1868.     scalar += cycloidal(index);
  1869.   }
  1870.  
  1871.   scalar = 0.5*(1.0+(scalar / (DBL)Number_Of_Waves));
  1872.  
  1873.   return(scalar);
  1874. }
  1875.  
  1876.  
  1877. /*****************************************************************************
  1878. *
  1879. * FUNCTION
  1880. *
  1881. *   waves_pigm
  1882. *
  1883. * INPUT
  1884. *
  1885. *   EPoint -- The point in 3d space at which the pattern
  1886. *   is evaluated.
  1887. *   TPat   -- Texture pattern struct
  1888. *
  1889. * OUTPUT
  1890. *
  1891. * RETURNS
  1892. *
  1893. *   DBL value in the range 0.0 to 1.0
  1894. *
  1895. * AUTHOR
  1896. *
  1897. *   POV-Ray Team
  1898. *
  1899. * DESCRIPTION   : Note this pattern is only used for pigments and textures.
  1900. *                 Normals have a specialized pattern for this.
  1901. *
  1902. * CHANGES
  1903. *   Nov 1994 : adapted from normal by [CY]
  1904. *
  1905. ******************************************************************************/
  1906.  
  1907. static DBL waves_pigm (EPoint, TPat)
  1908. VECTOR EPoint;
  1909. TPATTERN *TPat;
  1910. {
  1911.   register unsigned int i;
  1912.   register DBL length, index;
  1913.   DBL scalar = 0.0;
  1914.   VECTOR point;
  1915.  
  1916.   for (i = 0 ; i < Number_Of_Waves ; i++)
  1917.   {
  1918.     VSub (point, EPoint, Wave_Sources[i]);
  1919.     VLength (length, point);
  1920.  
  1921.     if (length == 0.0)
  1922.     {
  1923.       length = 1.0;
  1924.     }
  1925.  
  1926.     index = length * TPat->Frequency * frequency[i] + TPat->Phase;
  1927.  
  1928.     scalar += cycloidal(index)/frequency[i];
  1929.   }
  1930.  
  1931.   scalar = 0.2*(2.5+(scalar / (DBL)Number_Of_Waves));
  1932.  
  1933.   return(scalar);
  1934. }
  1935.  
  1936.  
  1937. /*****************************************************************************
  1938. *
  1939. * FUNCTION
  1940. *
  1941. *   dents_pigm
  1942. *
  1943. * INPUT
  1944. *
  1945. *   EPoint -- The point in 3d space at which the pattern
  1946. *   is evaluated.
  1947. *
  1948. * OUTPUT
  1949. *
  1950. * RETURNS
  1951. *
  1952. *   DBL value in the range 0.0 to 1.0
  1953. *   
  1954. * AUTHOR
  1955. *
  1956. *   POV-Ray Team
  1957. *   
  1958. * DESCRIPTION   : Note this pattern is only used for pigments and textures.
  1959. *                 Normals have a specialized pattern for this.
  1960. *
  1961. * CHANGES
  1962. *   Nov 1994 : adapted from normal by [CY]
  1963. *
  1964. ******************************************************************************/
  1965.  
  1966. static DBL dents_pigm (EPoint)
  1967. VECTOR EPoint;
  1968. {
  1969.   DBL noise;
  1970.  
  1971.   noise = Noise (EPoint);
  1972.  
  1973.   return(noise * noise * noise);
  1974. }
  1975.  
  1976.  
  1977.  
  1978. /*****************************************************************************
  1979. *
  1980. * FUNCTION
  1981. *
  1982. *   wrinkles_pigm
  1983. *
  1984. * INPUT
  1985. *
  1986. *   EPoint -- The point in 3d space at which the pattern
  1987. *   is evaluated.
  1988. *   
  1989. * OUTPUT
  1990. *   
  1991. * RETURNS
  1992. *
  1993. *   DBL value in the range 0.0 to 1.0
  1994. *   
  1995. * AUTHOR
  1996. *
  1997. *   POV-Ray Team
  1998. *   
  1999. * DESCRIPTION   : Note this pattern is only used for pigments and textures.
  2000. *                 Normals have a specialized pattern for this.
  2001. *
  2002. * CHANGES
  2003. *   Nov 1994 : adapted from normal by [CY]
  2004. *
  2005. ******************************************************************************/
  2006.  
  2007.  
  2008. static DBL wrinkles_pigm (EPoint)
  2009. VECTOR EPoint;
  2010. {
  2011.   register int i;
  2012.   DBL lambda = 2.0;
  2013.   DBL omega = 0.5;
  2014.   DBL value;
  2015.   VECTOR temp;
  2016.  
  2017.   value = Noise(EPoint);
  2018.  
  2019.   for (i = 1; i < 10; i++)
  2020.   {
  2021.     VScale(temp,EPoint,lambda);
  2022.  
  2023.     value += omega * Noise(temp);
  2024.  
  2025.     lambda *= 2.0;
  2026.  
  2027.     omega *= 0.5;
  2028.   }
  2029.  
  2030.   return(value/2.0);
  2031. }
  2032.  
  2033.  
  2034.  
  2035. /*****************************************************************************
  2036. *
  2037. * FUNCTION
  2038. *
  2039. *   quilted_pigm
  2040. *
  2041. * INPUT
  2042. *   
  2043. * OUTPUT
  2044. *   
  2045. * RETURNS
  2046. *   
  2047. * AUTHOR
  2048. *
  2049. *   Dan Farmer & Chris Young
  2050. *   
  2051. * DESCRIPTION
  2052. *
  2053. * CHANGES
  2054. *
  2055. ******************************************************************************/
  2056.  
  2057. static DBL quilted_pigm (EPoint, TPat)
  2058. VECTOR EPoint;
  2059. TPATTERN *TPat;
  2060. {
  2061.   VECTOR value;
  2062.   DBL t;
  2063.  
  2064.   value[X] = EPoint[X]-FLOOR(EPoint[X])-0.5;
  2065.   value[Y] = EPoint[Y]-FLOOR(EPoint[Y])-0.5;
  2066.   value[Z] = EPoint[Z]-FLOOR(EPoint[Z])-0.5;
  2067.  
  2068.   t = sqrt(value[X]*value[X]+value[Y]*value[Y]+value[Z]*value[Z]);
  2069.  
  2070.   t = quilt_cubic(t, TPat->Vals.Quilted.Control0, TPat->Vals.Quilted.Control1);
  2071.  
  2072.   value[X] *= t;
  2073.   value[Y] *= t;
  2074.   value[Z] *= t;
  2075.  
  2076.   return((fabs(value[X])+fabs(value[Y])+fabs(value[Z]))/3.0);
  2077. }
  2078.  
  2079.  
  2080.  
  2081. /*****************************************************************************
  2082. *
  2083. * FUNCTION
  2084. *
  2085. * INPUT
  2086. *
  2087. * OUTPUT
  2088. *
  2089. * RETURNS
  2090. *
  2091. * AUTHOR
  2092. *
  2093. * DESCRIPTION
  2094. *
  2095. * CHANGES
  2096. *
  2097. ******************************************************************************/
  2098.  
  2099. #define INV_SQRT_3_4 1.154700538
  2100. DBL quilt_cubic(t,p1,p2)
  2101. DBL t,p1,p2;
  2102. {
  2103.  DBL it=(1-t);
  2104.  DBL itsqrd=it*it;
  2105. /* DBL itcubed=it*itsqrd; */
  2106.  DBL tsqrd=t*t;
  2107.  DBL tcubed=t*tsqrd;
  2108.  DBL val;
  2109.  
  2110. /* Originally coded as...
  2111.  
  2112.  val= (DBL)(itcubed*n1+(tcubed)*n2+3*t*(itsqrd)*p1+3*(tsqrd)*(it)*p2);
  2113.  
  2114.  re-written by CEY to optimise because n1=0 n2=1 always.
  2115.  
  2116. */
  2117.  
  2118.  val = (tcubed + 3.0*t*itsqrd*p1 + 3.0*tsqrd*it*p2) * INV_SQRT_3_4;
  2119.  
  2120.  return(val);
  2121. }
  2122.  
  2123.  
  2124.  
  2125. /*****************************************************************************
  2126. *
  2127. * FUNCTION
  2128. *
  2129. * INPUT
  2130. *
  2131. * OUTPUT
  2132. *
  2133. * RETURNS
  2134. *
  2135. * AUTHOR
  2136. *
  2137. * DESCRIPTION
  2138. *
  2139. * CHANGES
  2140. *
  2141. ******************************************************************************/
  2142.  
  2143. void Search_Blend_Map (value,Blend_Map,Prev,Cur)
  2144. DBL value;
  2145. BLEND_MAP *Blend_Map;
  2146. BLEND_MAP_ENTRY **Prev, **Cur;
  2147. {
  2148.   BLEND_MAP_ENTRY *P, *C;
  2149.   int Max_Ent=Blend_Map->Number_Of_Entries-1;
  2150.  
  2151.   /* if greater than last, use last. */
  2152.  
  2153.   if (value >= Blend_Map->Blend_Map_Entries[Max_Ent].value)
  2154.   {
  2155.     P = C = &(Blend_Map->Blend_Map_Entries[Max_Ent]);
  2156.   }
  2157.   else
  2158.   {
  2159.     P = C = &(Blend_Map->Blend_Map_Entries[0]);
  2160.  
  2161.     while (value > C->value)
  2162.     {
  2163.       P = C++;
  2164.     }
  2165.   }
  2166.  
  2167.   if (value == C->value)
  2168.   {
  2169.     P = C;
  2170.   }
  2171.  
  2172.   *Prev = P;
  2173.   *Cur  = C;
  2174. }
  2175.  
  2176.  
  2177.  
  2178. /*****************************************************************************
  2179. *
  2180. * FUNCTION
  2181. *
  2182. * INPUT
  2183. *
  2184. * OUTPUT
  2185. *
  2186. * RETURNS
  2187. *
  2188. * AUTHOR
  2189. *
  2190. * DESCRIPTION
  2191. *
  2192. * CHANGES
  2193. *
  2194. ******************************************************************************/
  2195.  
  2196. static TURB *Search_For_Turb(Warps)
  2197. WARP *Warps;
  2198. {
  2199.   WARP* Temp=Warps;
  2200.  
  2201.   if (Temp!=NULL)
  2202.   {
  2203.     while (Temp->Next_Warp != NULL)
  2204.     {
  2205.       Temp=Temp->Next_Warp;
  2206.     }
  2207.  
  2208.     if (Temp->Warp_Type != CLASSIC_TURB_WARP)
  2209.     {
  2210.        Temp=NULL;
  2211.     }
  2212.   }
  2213.  
  2214.   return ((TURB *)Temp);
  2215. }
  2216.